home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / email / header.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-10-13  |  8.3 KB  |  328 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __all__ = [
  5.     'Header',
  6.     'decode_header',
  7.     'make_header']
  8. import re
  9. import binascii
  10. import email.quoprimime as email
  11. import email.base64mime as email
  12. from email.errors import HeaderParseError
  13. from email.charset import Charset
  14. NL = '\n'
  15. SPACE = ' '
  16. USPACE = u' '
  17. SPACE8 = ' ' * 8
  18. UEMPTYSTRING = u''
  19. MAXLINELEN = 76
  20. USASCII = Charset('us-ascii')
  21. UTF8 = Charset('utf-8')
  22. ecre = re.compile('\n  =\\?                   # literal =?\n  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset\n  \\?                    # literal ?\n  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive\n  \\?                    # literal ?\n  (?P<encoded>.*?)      # non-greedy up to the next ?= is the encoded string\n  \\?=                   # literal ?=\n  (?=[ \\t]|$)           # whitespace or the end of the string\n  ', re.VERBOSE | re.IGNORECASE | re.MULTILINE)
  23. fcre = re.compile('[\\041-\\176]+:$')
  24. _max_append = email.quoprimime._max_append
  25.  
  26. def decode_header(header):
  27.     header = str(header)
  28.     if not ecre.search(header):
  29.         return [
  30.             (header, None)]
  31.     
  32.     decoded = []
  33.     dec = ''
  34.     for line in header.splitlines():
  35.         if not ecre.search(line):
  36.             decoded.append((line, None))
  37.             continue
  38.         
  39.         parts = ecre.split(line)
  40.         while parts:
  41.             unenc = parts.pop(0).strip()
  42.             if unenc:
  43.                 if decoded and decoded[-1][1] is None:
  44.                     decoded[-1] = (decoded[-1][0] + SPACE + unenc, None)
  45.                 else:
  46.                     decoded.append((unenc, None))
  47.             
  48.             if parts:
  49.                 (charset, encoding) = [ s.lower() for s in parts[0:2] ]
  50.                 encoded = parts[2]
  51.                 dec = None
  52.                 if encoding == 'q':
  53.                     dec = email.quoprimime.header_decode(encoded)
  54.                 elif encoding == 'b':
  55.                     
  56.                     try:
  57.                         dec = email.base64mime.decode(encoded)
  58.                     except binascii.Error:
  59.                         []
  60.                         []
  61.                         raise HeaderParseError
  62.                     except:
  63.                         []<EXCEPTION MATCH>binascii.Error
  64.                     
  65.  
  66.                 []
  67.                 if dec is None:
  68.                     dec = encoded
  69.                 
  70.                 if decoded and decoded[-1][1] == charset:
  71.                     decoded[-1] = (decoded[-1][0] + dec, decoded[-1][1])
  72.                 else:
  73.                     decoded.append((dec, charset))
  74.             
  75.             del parts[0:3]
  76.     
  77.     return decoded
  78.  
  79.  
  80. def make_header(decoded_seq, maxlinelen = None, header_name = None, continuation_ws = ' '):
  81.     h = Header(maxlinelen = maxlinelen, header_name = header_name, continuation_ws = continuation_ws)
  82.     for s, charset in decoded_seq:
  83.         if charset is not None and not isinstance(charset, Charset):
  84.             charset = Charset(charset)
  85.         
  86.         h.append(s, charset)
  87.     
  88.     return h
  89.  
  90.  
  91. class Header:
  92.     
  93.     def __init__(self, s = None, charset = None, maxlinelen = None, header_name = None, continuation_ws = ' ', errors = 'strict'):
  94.         if charset is None:
  95.             charset = USASCII
  96.         
  97.         if not isinstance(charset, Charset):
  98.             charset = Charset(charset)
  99.         
  100.         self._charset = charset
  101.         self._continuation_ws = continuation_ws
  102.         cws_expanded_len = len(continuation_ws.replace('\t', SPACE8))
  103.         self._chunks = []
  104.         if s is not None:
  105.             self.append(s, charset, errors)
  106.         
  107.         if maxlinelen is None:
  108.             maxlinelen = MAXLINELEN
  109.         
  110.         if header_name is None:
  111.             self._firstlinelen = maxlinelen
  112.         else:
  113.             self._firstlinelen = maxlinelen - len(header_name) - 2
  114.         self._maxlinelen = maxlinelen - cws_expanded_len
  115.  
  116.     
  117.     def __str__(self):
  118.         return self.encode()
  119.  
  120.     
  121.     def __unicode__(self):
  122.         uchunks = []
  123.         lastcs = None
  124.         for s, charset in self._chunks:
  125.             nextcs = charset
  126.             if uchunks:
  127.                 if lastcs not in (None, 'us-ascii'):
  128.                     if nextcs in (None, 'us-ascii'):
  129.                         uchunks.append(USPACE)
  130.                         nextcs = None
  131.                     
  132.                 elif nextcs not in (None, 'us-ascii'):
  133.                     uchunks.append(USPACE)
  134.                 
  135.             
  136.             lastcs = nextcs
  137.             uchunks.append(unicode(s, str(charset)))
  138.         
  139.         return UEMPTYSTRING.join(uchunks)
  140.  
  141.     
  142.     def __eq__(self, other):
  143.         return other == self.encode()
  144.  
  145.     
  146.     def __ne__(self, other):
  147.         return not (self == other)
  148.  
  149.     
  150.     def append(self, s, charset = None, errors = 'strict'):
  151.         if charset is None:
  152.             charset = self._charset
  153.         elif not isinstance(charset, Charset):
  154.             charset = Charset(charset)
  155.         
  156.         if charset != '8bit':
  157.             if isinstance(s, str):
  158.                 if not charset.input_codec:
  159.                     pass
  160.                 incodec = 'us-ascii'
  161.                 ustr = unicode(s, incodec, errors)
  162.                 if not charset.output_codec:
  163.                     pass
  164.                 outcodec = 'us-ascii'
  165.                 ustr.encode(outcodec, errors)
  166.             elif isinstance(s, unicode):
  167.                 for charset in (USASCII, charset, UTF8):
  168.                     
  169.                     try:
  170.                         if not charset.output_codec:
  171.                             pass
  172.                         outcodec = 'us-ascii'
  173.                         s = s.encode(outcodec, errors)
  174.                     continue
  175.                     except UnicodeError:
  176.                         continue
  177.                     
  178.  
  179.                 
  180.             
  181.         
  182.         self._chunks.append((s, charset))
  183.  
  184.     
  185.     def _split(self, s, charset, maxlinelen, splitchars):
  186.         splittable = charset.to_splittable(s)
  187.         encoded = charset.from_splittable(splittable, True)
  188.         elen = charset.encoded_header_len(encoded)
  189.         if elen <= maxlinelen:
  190.             return [
  191.                 (encoded, charset)]
  192.         
  193.         if charset == '8bit':
  194.             return [
  195.                 (s, charset)]
  196.         elif charset == 'us-ascii':
  197.             return self._split_ascii(s, charset, maxlinelen, splitchars)
  198.         elif elen == len(s):
  199.             splitpnt = maxlinelen
  200.             first = charset.from_splittable(splittable[:splitpnt], False)
  201.             last = charset.from_splittable(splittable[splitpnt:], False)
  202.         else:
  203.             (first, last) = _binsplit(splittable, charset, maxlinelen)
  204.         fsplittable = charset.to_splittable(first)
  205.         fencoded = charset.from_splittable(fsplittable, True)
  206.         chunk = [
  207.             (fencoded, charset)]
  208.         return chunk + self._split(last, charset, self._maxlinelen, splitchars)
  209.  
  210.     
  211.     def _split_ascii(self, s, charset, firstlen, splitchars):
  212.         chunks = _split_ascii(s, firstlen, self._maxlinelen, self._continuation_ws, splitchars)
  213.         return zip(chunks, [
  214.             charset] * len(chunks))
  215.  
  216.     
  217.     def _encode_chunks(self, newchunks, maxlinelen):
  218.         chunks = []
  219.         for header, charset in newchunks:
  220.             if not header:
  221.                 continue
  222.             
  223.             if charset is None or charset.header_encoding is None:
  224.                 s = header
  225.             else:
  226.                 s = charset.header_encode(header)
  227.             if chunks and chunks[-1].endswith(' '):
  228.                 extra = ''
  229.             else:
  230.                 extra = ' '
  231.             _max_append(chunks, s, maxlinelen, extra)
  232.         
  233.         joiner = NL + self._continuation_ws
  234.         return joiner.join(chunks)
  235.  
  236.     
  237.     def encode(self, splitchars = ';, '):
  238.         newchunks = []
  239.         maxlinelen = self._firstlinelen
  240.         lastlen = 0
  241.         for s, charset in self._chunks:
  242.             targetlen = maxlinelen - lastlen - 1
  243.             if targetlen < charset.encoded_header_len(''):
  244.                 targetlen = maxlinelen
  245.             
  246.             newchunks += self._split(s, charset, targetlen, splitchars)
  247.             (lastchunk, lastcharset) = newchunks[-1]
  248.             lastlen = lastcharset.encoded_header_len(lastchunk)
  249.         
  250.         return self._encode_chunks(newchunks, maxlinelen)
  251.  
  252.  
  253.  
  254. def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars):
  255.     lines = []
  256.     maxlen = firstlen
  257.     for line in s.splitlines():
  258.         line = line.lstrip()
  259.         if len(line) < maxlen:
  260.             lines.append(line)
  261.             maxlen = restlen
  262.             continue
  263.         
  264.         for ch in splitchars:
  265.             if ch in line:
  266.                 break
  267.                 continue
  268.         else:
  269.             maxlen = restlen
  270.         cre = re.compile('%s\\s*' % ch)
  271.         if ch in ';,':
  272.             eol = ch
  273.         else:
  274.             eol = ''
  275.         joiner = eol + ' '
  276.         joinlen = len(joiner)
  277.         wslen = len(continuation_ws.replace('\t', SPACE8))
  278.         this = []
  279.         linelen = 0
  280.         for part in cre.split(line):
  281.             curlen = linelen + max(0, len(this) - 1) * joinlen
  282.             partlen = len(part)
  283.             onfirstline = not lines
  284.             if ch == ' ' and onfirstline and len(this) == 1 and fcre.match(this[0]):
  285.                 this.append(part)
  286.                 linelen += partlen
  287.                 continue
  288.             if curlen + partlen > maxlen:
  289.                 if this:
  290.                     lines.append(joiner.join(this) + eol)
  291.                 
  292.                 if partlen > maxlen and ch != ' ':
  293.                     subl = _split_ascii(part, maxlen, restlen, continuation_ws, ' ')
  294.                     lines.extend(subl[:-1])
  295.                     this = [
  296.                         subl[-1]]
  297.                 else:
  298.                     this = [
  299.                         part]
  300.                 linelen = wslen + len(this[-1])
  301.                 maxlen = restlen
  302.                 continue
  303.             this.append(part)
  304.             linelen += partlen
  305.         
  306.         if this:
  307.             lines.append(joiner.join(this))
  308.             continue
  309.     
  310.     return lines
  311.  
  312.  
  313. def _binsplit(splittable, charset, maxlinelen):
  314.     i = 0
  315.     j = len(splittable)
  316.     while i < j:
  317.         m = i + j + 1 >> 1
  318.         chunk = charset.from_splittable(splittable[:m], True)
  319.         chunklen = charset.encoded_header_len(chunk)
  320.         if chunklen <= maxlinelen:
  321.             i = m
  322.             continue
  323.         j = m - 1
  324.     first = charset.from_splittable(splittable[:i], False)
  325.     last = charset.from_splittable(splittable[i:], False)
  326.     return (first, last)
  327.  
  328.